home *** CD-ROM | disk | FTP | other *** search
- Subject: v23i077: Xmodem file transfer program, revision3.9, Part01/03
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 02329e80 c9389d8c ced0b526 9fb92597
-
- Submitted-by: Steve Grandi <grandi@noao.edu>
- Posting-number: Volume 23, Issue 77
- Archive-name: xmodem3.9/part01
-
- The xmodem program implements the Christensen (XMODEM) file transfer
- protocol for moving files between 4.2/4.3BSD Unix systems (and successors,
- including Suns) and microcomputers. The XMODEM/CRC protocol, the MODEM7
- batch protocol, the XMODEM-1K block protocol, the YMODEM batch protocol
- and the YMODEM-G streaming protocol are all supported by xmodem. The
- ZMODEM protocol is not supported.
-
- This is version 3.9 (circa 11/90) of the xmodem program which incorporates
- a few bugfixes (one important!) and some enhancements: 1) status messages
- when running xmodem through Sun's tip program ("p" flag); 2) delayed
- startup (via the "w" flag); 3) ability to turn off EOT verification (via
- "e" flag); 4) ability to allow CAN-CAN abort in the midst of a file
- transfer (via "n" flag) and 5) YMODEM-G support (via the "g" flag). See
- update.doc for details.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: README Makefile receive.c xmodem.c
- # Wrapped by rsalz@litchi.bbn.com on Wed Dec 5 12:31:56 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 1 (of 3)."'
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(21493 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThis is version 3.9 (circa 11/90) of the xmodem program which incorporates
- Xa few bugfixes (one important!) and some enhancements: 1) status messages
- Xwhen running xmodem through Sun's tip program ("p" flag); 2) delayed
- Xstartup (via the "w" flag); 3) ability to turn off EOT verification (via
- X"e" flag); 4) ability to allow CAN-CAN abort in the midst of a file
- Xtransfer (via "n" flag) and 5) YMODEM-G support (via the "g" flag). See
- Xupdate.doc for details.
- X
- X--------------------------------------------------------------------------------
- X
- XThis is version 3.8 (circa 11/88) of the xmodem program which incorporates
- Xminor enhancements over version 3.7 which incoporates minor enhancements
- Xover version 3.6. See update.doc.
- X
- X--------------------------------------------------------------------------------
- X
- XThis is version 3.6 (finished 4/88) of the xmodem program which includes a
- Xfew bugfixes and some enhancements (requested by Macintosh users)
- Xstimulated by the xmodem release through comp.sources.unix. See the file
- Xupdate.doc for details.
- X
- X--------------------------------------------------------------------------------
- X
- XThis is version 3.4 (finished 10/87) of the xmodem program, a full-featured
- XXMODEM implementation for 4.3BSD. Since the previous release (version
- X3.2, see volume 7 of the archives), substantial improvements have been
- Xmade. See the file update.doc for details. Also, some attempt has been
- Xmade to support SysV Unix systems; see below.
- X
- XAs far as I am concerned, this program has reached the end of its evolution.
- XNewer protocols (such as ZMODEM) will not be incorporated into xmodem. Check
- Xout Chuck Forsberg's rz/sz programs if you are interested in ZMODEM.
- X
- X--------------------------------------------------------------------------------
- X
- XThe xmodem program implements the Christensen (XMODEM) file transfer
- Xprotocol for moving files between 4.2/4.3BSD Unix systems and microcomputers.
- XThe XMODEM/CRC protocol, the MODEM7 batch protocol, the XMODEM-1K
- Xblock protocol and the YMODEM batch protocol are all supported by xmodem.
- XFor details of the protocols, see the document edited by Chuck Forsberg titled
- XXMODEM/YMODEM Protocol Reference (the latest version is dated 6-18-88).
- X
- XThis program runs on 4.2/4.3BSD systems ONLY. It has been tested on VAXes
- Xand Suns against the MEX-PC program from Niteowl Software and the ZCOMM and
- XDSZ programs from Omen Technology.
- X
- XI have tried to keep the 4.2isms (select system call, 4.2BSD/v7 tty structures,
- Xgettimeofday system call, etc.) confined to the source file getput.c; but I
- Xmake no guarantees. Also, I have made no attempt to keep variable names
- Xunder 7 characters. A version of getput.c that MAY work on Sys V Unix
- Xsystems is included.
- X
- X--------------------------------------------------------------------------------
- X
- XThanks to Emmet Gray (ihnp4!uiucuxc!fthood!egray) and John Rupley
- X(arizona!rupley!root) for the following notes about converting xmodem to Sys V.
- XSince I don't have a Sys V system to test a Sys V version, I won't even try.
- X
- X1) Change the includes in xmodem.h from <sys/time.h> to <time.h>
- X and from <sgtty.h> to <termio.h>
- X
- X2) Convert the occurrences of rindex to strrchr in batch.c
- X
- X3) Substitute getput.sysv.c for getput.c
- X
- XA further "gotcha" regarding Sys V is contained in the following message :
- X
- XFrom: Bill Stubblebine <hplsdls!was@hp-lsd.UUCP>
- XDate: Sat, 25 Jun 88 13:36:20 mdt
- XTo: grandi@noao.arizona.edu
- XSubject: xmodem3.6 bug, fix and THANKS!!
- X
- X 1:30 PM MDT
- X June 25, 1988
- X
- XFirst, thanks for posting a really useful program, xmodem 3.6.
- X
- XI installed the xmodem program on an HP 9000 Series 350 workstation,
- Xrunning HP-UX version 6.01 (AT&T System V compatible) to talk to my
- XCP/M system at home. MODEM7 batch is particularly useful.
- X
- XI'd like to report a bug I found and the fix I developed in the source
- Xfile getput.sysv.c so that you can include it in future releases.
- X
- XI've reproduced the relevant portion of getput.sysv.c, modified to fix
- Xthe bug, at the end of this file. See the routine getspeed() starting
- Xat line 382. Getspeed() derives the serial port speed from the
- Xc_cflag ioctl parameter, for use in estimating transmission times.
- X
- XI suspected something was wrong when xmodem kept reporting 1200 baud
- Xmodem connections as 1800 baud in the log file, but the transfers
- Xstill worked OK at 1200 baud. However, I also have a Courier HST 9600
- Xbaud modem at home, and when I tried 9600 baud xmodem transfers,
- Xxmodem would core dump on the UNIX host.
- X
- XOn line 386 of getput.sysv.c, in the procedure getspeed(), an array is
- Xdeclared containing numerical constants representing the various baud
- Xrates supported by the host terminal interface. The appropriate baud
- Xrate constant is selected by the statements in lines 392-394, which
- Xmask the c_cflag baud rate bitfield to index into the speedtbl[]
- Xarray.
- X
- XThere are two problems here. The first problem is that speedtbl[] is
- Xmissing some valid baud rate entries, as the modified declaration
- Xshows. I got the entries for the modified declaration from the
- Xtermio(7) manpage in my System V user's manual. The missing entries
- Xthrow off the indexing arithmetic. Notice, for example, that the
- Xmissing entry 900 was responsible for mapping the c_cflag bits for
- X1200 baud to the 1800 baud constant.
- X
- XOriginal declaration:
- X static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- X 1200, 1800, 2400, 4800, 9600, 19200, 0};
- X
- XModified declaration:
- X static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- X 900, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 19200, 38400, 0};
- X ^^^ ^^^^ ^^^^ ^^^^^ ^^^^^
- X
- XThe second problem didn't show up until I used 9600 baud. The c_cflag
- Xbitfield value for 9600 baud is 16 decimal (020 octal). The masking
- Xconstant in lines 392-394 was originally 017 octal, which masked the
- X9600 baud bitfield to 0, indexing to the speedtbl[] value of 0. Speed
- Xcalculations using a baudrate of 0 caused floating point exceptions
- Xleading to the host core dumps at 9600 baud.
- X
- XI changed the mask value from 017 octal to 037 octal (which is
- Xactually the size of the c_cflag baudrate field), and changed the
- Xlimit test in line 392 from 14 to 18, the new correct number of
- Xelements in the speedtbl[] array.
- X
- XI'm not familiar with 4.2BSD, but I noticed that getput.c, the 4.2BSD
- Xversion of the I/O routines, contains virtually the same code for
- Xdetermining the baudrate as that in getput.sysv.c. It may be OK for
- X4.2BSD, but definitely not for System V.
- X
- XThe modified code now works great at all baud rates! Thanks again for
- Xposting the program.
- X
- X Bill Stubblebine
- X Hewlett-Packard Logic Systems Div.
- X 8245 N. Union Blvd.
- X Colorado Springs, Co. 80918
- X ARPA: was%hp-lsd@hplabs.hp.com
- X UUCP: {hplabs,hpfcla}!{hpldola,hp-lsd}!was
- X
- X--------------------------------------------------------------------------------
- X
- XA common request to me concerns running xmodem through tip in order to do
- XXMODEM or YMODEM transfers. I have discovered that SunOS has a nice
- Xfeature in tip (accessed through ~C) that connects a named program to a
- Xremote machine. It turns out that 4.3BSD tip has a similar (but
- Xundocumented) feature, but far less convenient: SunOS tip connects file
- Xdescriptor 0 of the program to the remote line input and file descriptor 1
- Xto remote line output while 4.3BSD connects up file descriptors 3 and 4!
- X
- XIf you would like to use xmodem through 4.3BSD tip, the following message
- Xshould be of interest (note that the patches given below are against an old
- Xversion of the source):
- X
- XTo: grandi@noao.edu (Steve Grandi CCS)
- XSubject: Re: xmodem
- XDate: Tue, 02 Jan 90 12:34:58 -0500
- XFrom: Benson I. Margulies <benson@odi.com>
- X
- X
- X Yes, I would like to receive the changes!
- X
- X Steve, grandi@noao.edu
- X
- XOK, here are the diffs. I've tested them in receive mode,
- Xbut I haven't been able to verify that they work for sending.
- XThe reason why is a long sob story.
- X
- XIt would be good to do two additional things:
- X
- X1) add some \r's to the messages printed.
- X2) when in tip mode, print more messages on stdout
- Xto report progress, like a . every 100 blocks.
- X
- XRCS file: RCS/xmodem.c,v
- Xretrieving revision 1.1
- Xretrieving revision 1.2
- Xdiff -c -r1.1 -r1.2
- X*** /tmp/,RCSt1a02154 Tue Jan 2 12:33:12 1990
- X--- /tmp/,RCSt2a02154 Tue Jan 2 12:33:12 1990
- X***************
- X*** 52,57 ****
- X--- 52,60 ----
- X MDM7BAT = FALSE; /* no MODEM7 batch mode */
- X YMDMBAT = FALSE; /* no YMODEM batch mode */
- X TOOBUSY = FALSE; /* not too busy for sleeping in packet read */
- X+ INFD = 0;
- X+ OUTFD = 1;
- X+ FDS_DISTINCT = 0;
- X
- X fprintf(stderr, "XMODEM Version %d.%d", VERSION/10, VERSION%10);
- X fprintf(stderr, " -- UNIX-Microcomputer Remote File Transfer Facility\n");
- X***************
- X*** 101,106 ****
- X--- 104,115 ----
- X case 's' : SENDFLAG = TRUE; /* send file */
- X XMITTYPE = gettype(argv[1][index++]);
- X break;
- X+ case 'p': /* TIP */
- X+ case 'P':
- X+ INFD = 3;
- X+ OUTFD = 4;
- X+ FDS_DISTINCT = TRUE;
- X+ break;
- X default : fprintf(stderr, "Invalid Flag %c ignored\n", flag);
- X break;
- X }
- X***************
- X*** 120,133 ****
- X LOGFP = fopen(fname, "w"); /* new LOG file */
- X if (!LOGFP)
- X error("Fatal - Can't Open Log File", FALSE);
- X
- X fprintf(LOGFP,"\n++++++++ %s", stamptime());
- X fprintf(LOGFP,"XMODEM Version %d.%d\n", VERSION/10, VERSION%10);
- X fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
- X! for (index=2; index<argc; ++index)
- X! fprintf(LOGFP, " %s", argv[index]);
- X fprintf(LOGFP, "\n");
- X! }
- X
- X getspeed(); /* get tty-speed for time estimates */
- X
- X--- 129,147 ----
- X LOGFP = fopen(fname, "w"); /* new LOG file */
- X if (!LOGFP)
- X error("Fatal - Can't Open Log File", FALSE);
- X+ setlinebuf(LOGFP);
- X
- X fprintf(LOGFP,"\n++++++++ %s", stamptime());
- X+
- X fprintf(LOGFP,"XMODEM Version %d.%d\n", VERSION/10, VERSION%10);
- X+
- X fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
- X!
- X! for (index=2; index<argc; ++index) {
- X! fprintf(LOGFP, " %s", argv[index]);
- X! }
- X fprintf(LOGFP, "\n");
- X! }
- X
- X getspeed(); /* get tty-speed for time estimates */
- X
- X===================================================================
- XRCS file: RCS/xmodem.h,v
- Xretrieving revision 1.1
- Xretrieving revision 1.2
- Xdiff -c -r1.1 -r1.2
- X*** /tmp/,RCSt1a02154 Tue Jan 2 12:33:13 1990
- X--- /tmp/,RCSt2a02154 Tue Jan 2 12:33:14 1990
- X***************
- X*** 10,16 ****
- X #define logit(string) if(LOGFLAG)fprintf(LOGFP,string)
- X #define logitarg(string,argument) if(LOGFLAG)fprintf(LOGFP,string,argument)
- X
- X! #define VERSION 36 /* Version Number */
- X #define FALSE 0
- X #define TRUE 1
- X
- X--- 10,16 ----
- X #define logit(string) if(LOGFLAG)fprintf(LOGFP,string)
- X #define logitarg(string,argument) if(LOGFLAG)fprintf(LOGFP,string,argument)
- X
- X! #define VERSION 37 /* Version Number */
- X #define FALSE 0
- X #define TRUE 1
- X
- X***************
- X*** 73,78 ****
- X--- 73,81 ----
- X int YMDMBAT; /* YMODEM batch protocol */
- X int TOOBUSY; /* turn off sleeping in packet read routine */
- X int CHECKLENGTH; /* Are we truncating a file to a YMODEM length? */
- X+ int INFD; /* file descriptor for protocol reading */
- X+ int OUTFD; /* file descriptor for protocol reading */
- X+ int FDS_DISTINCT; /* in,out fd's not 0 and 1 */
- X
- X
- X /* CRC-16 constants. From Usenet contribution by Mark G. Mendel,
- X===================================================================
- XRCS file: RCS/getput.c,v
- Xretrieving revision 1.1
- Xretrieving revision 1.2
- Xdiff -c -r1.1 -r1.2
- X*** /tmp/,RCSt1a02154 Tue Jan 2 12:33:14 1990
- X--- /tmp/,RCSt2a02154 Tue Jan 2 12:33:15 1990
- X***************
- X*** 4,9 ****
- X--- 4,10 ----
- X */
- X
- X #include "xmodem.h"
- X+ #include <sys/types.h>
- X
- X /*
- X *
- X***************
- X*** 103,113 ****
- X /* get a byte from data stream -- timeout if "seconds" elapses */
- X /* This routine is VERY 4.2 specific */
- X
- X int
- X readbyte(seconds)
- X int seconds;
- X {
- X- int readfd;
- X char c;
- X struct timeval tmout;
- X
- X--- 104,122 ----
- X /* get a byte from data stream -- timeout if "seconds" elapses */
- X /* This routine is VERY 4.2 specific */
- X
- X+ int select_input (tmout)
- X+ struct timeval * tmout;
- X+ {
- X+ fd_set readfd; /* mask for select call */
- X+ FD_ZERO(&readfd);
- X+ FD_SET(INFD, &readfd);
- X+ return select(getdtablesize(), &readfd, (int *)0, (int *)0, tmout);
- X+ }
- X+
- X int
- X readbyte(seconds)
- X int seconds;
- X {
- X char c;
- X struct timeval tmout;
- X
- X***************
- X*** 114,125 ****
- X tmout.tv_sec = seconds;
- X tmout.tv_usec = 0;
- X
- X- readfd = 1<<0;
- X
- X! if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
- X! return(TIMEOUT);
- X
- X! read(0, &c, 1);
- X
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
- X--- 123,133 ----
- X tmout.tv_sec = seconds;
- X tmout.tv_usec = 0;
- X
- X
- X! if (select_input(&tmout) == 0)
- X! return(TIMEOUT);
- X
- X! read(INFD, &c, 1);
- X
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
- X***************
- X*** 138,151 ****
- X /* set up a usec timeout on stdin */
- X tmout.tv_sec = 0;
- X tmout.tv_usec = 1;
- X! readfd = 1<<0;
- X
- X /* any characters pending?; return if none */
- X! if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
- X! return;
- X
- X /* read the characters to flush them (assume there are fewer than BBUFSIZ */
- X! (void) read(0, inbuf, BBUFSIZ);
- X }
- X--- 146,159 ----
- X /* set up a usec timeout on stdin */
- X tmout.tv_sec = 0;
- X tmout.tv_usec = 1;
- X! readfd = 1<<INFD;
- X
- X /* any characters pending?; return if none */
- X! if (select_input(&tmout) == 0)
- X! return;
- X
- X /* read the characters to flush them (assume there are fewer than BBUFSIZ */
- X! (void) read(INFD, inbuf, BBUFSIZ);
- X }
- X***************
- X*** 170,181 ****
- X long recvsectcnt; /* running sector count (128 byte sectors) */
- X
- X {
- X- int readfd; /* mask for select call */
- X- struct timeval tmout; /* timeout structure for select */
- X int numread; /* number of chars read */
- X int left; /* number of chars left to read */
- X int recfin = FALSE; /* flag that EOF read */
- X char inbuf[BBUFSIZ]; /* buffer for incoming packet */
- X register unsigned char c; /* character being processed */
- X register unsigned short chksm; /* working copy of checksum */
- X register int bfctr; /* working copy of bufctr */
- X--- 178,188 ----
- X long recvsectcnt; /* running sector count (128 byte sectors) */
- X
- X {
- X int numread; /* number of chars read */
- X int left; /* number of chars left to read */
- X int recfin = FALSE; /* flag that EOF read */
- X char inbuf[BBUFSIZ]; /* buffer for incoming packet */
- X+ struct timeval tmout; /* timeout structure for select */
- X register unsigned char c; /* character being processed */
- X register unsigned short chksm; /* working copy of checksum */
- X register int bfctr; /* working copy of bufctr */
- X***************
- X*** 184,190 ****
- X
- X tmout.tv_sec = seconds;
- X tmout.tv_usec = 0;
- X- readfd = 1<<0;
- X chksm = 0;
- X bfctr = 0;
- X
- X--- 191,196 ----
- X***************
- X*** 192,201 ****
- X
- X /* read however many chars are waiting */
- X
- X! if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
- X! return(TIMEOUT);
- X
- X! numread = read(0, inbuf, left);
- X left -= numread;
- X
- X if (DEBUG)
- X--- 198,207 ----
- X
- X /* read however many chars are waiting */
- X
- X! if (select_input(&tmout) == 0)
- X! return(TIMEOUT);
- X
- X! numread = read(INFD, inbuf, left);
- X left -= numread;
- X
- X if (DEBUG)
- X***************
- X*** 275,281 ****
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
- X
- X! if (write(1, &data, 1) != 1) /* write the byte (assume it goes NOW; no flushing needed) */
- X error ("Write error on stream", TRUE);
- X return;
- X }
- X--- 281,287 ----
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
- X
- X! if (write(OUTFD, &data, 1) != 1) /* write the byte (assume it goes NOW; no flushing needed) */
- X error ("Write error on stream", TRUE);
- X return;
- X }
- X***************
- X*** 289,295 ****
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
- X
- X! if (write(1, buffer, nbytes) != nbytes) /* write the buffer (assume no TIOCFLUSH needed) */
- X error ("Write error on stream", TRUE);
- X return;
- X }
- X--- 295,301 ----
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
- X
- X! if (write(OUTFD, buffer, nbytes) != nbytes) /* write the buffer (assume no TIOCFLUSH needed) */
- X error ("Write error on stream", TRUE);
- X return;
- X }
- X***************
- X*** 302,308 ****
- X int milliseconds;
- X {
- X struct timeval timeout;
- X- int readfd;
- X
- X if (milliseconds == 0)
- X return;
- X--- 308,313 ----
- X***************
- X*** 310,318 ****
- X fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds);
- X timeout.tv_sec = 0;
- X timeout.tv_usec = milliseconds * 1000;
- X- readfd = 0;
- X
- X! (void) select(1, &readfd, (int *)0, (int *)0, &timeout);
- X }
- X--- 315,322 ----
- X fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds);
- X timeout.tv_sec = 0;
- X timeout.tv_usec = milliseconds * 1000;
- X
- X! (void) select(0, (int *)0, (int *)0, (int *)0, &timeout);
- X }
- X***************
- X*** 335,344 ****
- X extern onintr();
- X
- X sleep(2); /* let the output appear */
- X! if (ioctl(0,TIOCGETP,&ttys)<0) /* get tty params [V7] */
- X error("Can't get TTY Parameters", TRUE);
- X
- X! tty = ttyname(0); /* identify current tty */
- X
- X ttysnew.sg_ispeed = ttys.sg_ispeed; /* copy input speed */
- X ttysnew.sg_ospeed = ttys.sg_ospeed; /* copy input speed */
- X--- 339,348 ----
- X extern onintr();
- X
- X sleep(2); /* let the output appear */
- X! if (ioctl(INFD,TIOCGETP,&ttys)<0) /* get tty params [V7] */
- X error("Can't get TTY Parameters", TRUE);
- X
- X! tty = ttyname(INFD); /* identify current tty */
- X
- X ttysnew.sg_ispeed = ttys.sg_ispeed; /* copy input speed */
- X ttysnew.sg_ospeed = ttys.sg_ospeed; /* copy input speed */
- X***************
- X*** 347,358 ****
- X ttysnew.sg_flags &= ~TANDEM; /* turn off flow control */
- X
- X /* set new paramters */
- X! if (ioctl(0,TIOCSETP,&ttysnew) < 0)
- X error("Can't set new TTY Parameters", TRUE);
- X
- X /* Flush characters waiting for read or write */
- X n = 0;
- X! if (ioctl(0,TIOCFLUSH,&n) < 0)
- X error("Can't flush terminal queue", TRUE);
- X
- X /* get tty status */
- X--- 351,362 ----
- X ttysnew.sg_flags &= ~TANDEM; /* turn off flow control */
- X
- X /* set new paramters */
- X! if (ioctl(INFD,TIOCSETP,&ttysnew) < 0)
- X error("Can't set new TTY Parameters", TRUE);
- X
- X /* Flush characters waiting for read or write */
- X n = 0;
- X! if (ioctl(INFD,TIOCFLUSH,&n) < 0)
- X error("Can't flush terminal queue", TRUE);
- X
- X /* get tty status */
- X***************
- X*** 381,387 ****
- X if (wason)
- X if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
- X error("Can't change TTY mode", FALSE);
- X! if (ioctl(0,TIOCSETP,&ttys) < 0)
- X { if (!errcall)
- X error("RESET - Can't restore normal TTY Params", FALSE);
- X else
- X--- 385,391 ----
- X if (wason)
- X if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
- X error("Can't change TTY mode", FALSE);
- X! if (ioctl(INFD,TIOCSETP,&ttys) < 0)
- X { if (!errcall)
- X error("RESET - Can't restore normal TTY Params", FALSE);
- X else
- X***************
- X*** 423,429 ****
- X {
- X static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- X 1200, 1800, 2400, 4800, 9600, 19200, 0};
- X! if (ioctl(0,TIOCGETP,&ttys) < 0) /* get tty structure */
- X error("Can't get TTY parameters", FALSE);
- X
- X if (ttys.sg_ispeed >= 0 && ttys.sg_ispeed <= 14)
- X--- 427,433 ----
- X {
- X static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
- X 1200, 1800, 2400, 4800, 9600, 19200, 0};
- X! if (ioctl(INFD,TIOCGETP,&ttys) < 0) /* get tty structure */
- X error("Can't get TTY parameters", FALSE);
- X
- X if (ttys.sg_ispeed >= 0 && ttys.sg_ispeed <= 14)
- X
- X--------------------------------------------------------------------------------
- X
- Xxmodem Program history:
- X
- XDescended from UMODEM 3.5 by Lauren Weinstein, Richard Conn, and others.
- X
- XBased on XMODEM Version 1.0 by Brian Kantor, UCSD (3/84) (Don't blame him
- X in any way for what follows....)
- X
- XVersion 2.0 (CRC-16 and Modem7 batch file transfer) (5/85) (Thanks to D'Anne
- X Thompson for the batch transfer code).
- X
- XVersion 2.1 (1K packets) (7/85)
- X
- XVersion 2.2 (general clean-ups and multi-character read speed-ups) (9/85)
- X
- XVersion 2.3 (nap while reading packets; split into several source files) (1/86)
- X
- XVersion 3.0 (Ymodem batch receive; associated changes) (2/86)
- X
- XVersion 3.1 (Ymodem batch send; associated changes) (8/86)
- X
- XVersion 3.2 (general cleanups) (9/86)
- X (Released to the world 1/87)
- X
- XVersion 3.3 (general fixes and cleanups; see update.doc) (5/87)
- X
- XVersion 3.4 (general fixes and cleanups; see update.doc) (10/87)
- X (Released to the world 3/88)
- X
- XVersion 3.5 (general fixes and cleanups; see update.doc) (3/88)
- X
- XVersion 3.6 (general fixes and cleanups; text file translation for Mac;
- X see update.doc) (4/88)
- X (Released to the world 4/88)
- X
- XVersion 3.7 (general fixes and cleanups; see update.doc) (5/88)
- X
- XVersion 3.8 (general fixes and cleanups; see update.doc) (11/88)
- X
- XVersion 3.9 (general fixes and cleanups; Sun tip support;
- X see update.doc) (11/90)
- X
- X--------------------------------------------------------------------------------
- X
- XPlease send bug fixes, additions and comments to:
- XSteve Grandi, National Optical Astronomy Observatories (Tucson, Arizona, USA)
- X grandi@noao.edu
- END_OF_FILE
- if test 21493 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(914 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- XOBJECTS = xmodem.o getput.o misc.o send.o receive.o batch.o
- XCFLAGS = -O
- X
- Xxmodem: $(OBJECTS)
- X cc $(CFLAGS) $(OBJECTS) -o xmodem
- X
- X$(OBJECTS): xmodem.h
- X
- Xprint:
- X lpr -p -Pvmslp xmodem.h xmodem.c getput.c receive.c send.c batch.c \
- X misc.c Makefile update.doc README xmodem.1 getput.sysv.c
- X
- Xlint:
- X lint xmodem.c getput.c receive.c send.c batch.c misc.c | imprint
- X
- Xshar:
- X shar README Makefile xmodem.1 xmodem.h > xmodem.shar.1
- X shar update.doc xmodem.c receive.c > xmodem.shar.2
- X shar getput.c getput.sysv.c > xmodem.shar.3
- X shar misc.c batch.c send.c > xmodem.shar.4
- X shar ymodem.doc > xmodem.shar.5
- X
- Xbigshar:
- X shar README update.doc Makefile xmodem.1 xmodem.h xmodem.c getput.c \
- X getput.sysv.c receive.c misc.c batch.c send.c > xmodem.shar
- X
- Xtarz:
- X tar cvf xmodem.tar README update.doc Makefile xmodem.1 xmodem.h \
- X xmodem.c getput.c getput.sysv.c receive.c misc.c batch.c send.c \
- X ymodem.doc
- X compress xmodem.tar
- END_OF_FILE
- if test 914 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'receive.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'receive.c'\"
- else
- echo shar: Extracting \"'receive.c'\" \(17709 characters\)
- sed "s/^X//" >'receive.c' <<'END_OF_FILE'
- X#include "xmodem.h"
- X
- X/** receive a file **/
- X
- X/* returns TRUE if in the midst of a batch transfer */
- X/* returns FALSE if no more files are coming */
- X
- X/* This routine is one HUGE do-while loop with far to many indented levels.
- X * I chose this route to facilitate error processing and to avoid GOTOs.
- X * Given the troubles I've had keeping the nested IF statements straight,
- X * I was probably mistaken...
- X */
- X
- Xrfile(name)
- Xchar *name;
- X{
- X
- Xchar *sectdisp();
- Xchar *cpm_unix();
- Xchar *strcpy();
- Xchar *ctime();
- Xtime_t time();
- X
- Xint fd, /* file descriptor for created file */
- Xchecksum, /* packet checksum */
- Xfirstchar, /* first character of a packet */
- Xsectnum, /* number of last received packet (modulo 128) */
- Xsectcurr, /* second byte of packet--should be packet number (mod 128) */
- Xsectcomp, /* third byte of packet--should be complement of sectcurr */
- Xtmode, /* text mode if true */
- Xamode, /* apple mode if true */
- Xerrors, /* count of errors for each packet */
- Xsterrors, /* count of errors during startup handshake */
- Xerrorflag, /* set true when packet (or first char of putative packet) is invalid */
- Xfatalerror, /* set within main "read-packet" Do-While when bad error found */
- Xinchecksum, /* incoming checksum or CRC */
- Xexpsect, /* expected number of sectors (YMODEM batch) */
- Xfirstwait, /* seconds to wait for first character in a packet */
- Xnocancanabort, /* if true, don't allow CAN-CAN abort */
- Xbufsize; /* packet size (128 or 1024) */
- Xlong recvsectcnt; /* running sector count (128 byte sectors) */
- Xlong modtime; /* Unix style file mod time from YMODEM header */
- Xint filemode; /* Unix style file mode from YMODEM header */
- Xint serial; /* serial # from YMODEM header */
- Xint filesleft; /* # of files left from YMODEM header */
- Xlong totalleft; /* # of bytes left from YMODEM header */
- Xint yfiletype; /* file type from YMODEM header */
- Xlong readbackup; /* "backup" value for characters read in file */
- Xtime_t timep[2]; /* used in setting mod time of received file */
- Xchar *p; /* generic pointer */
- Xint bufctr; /* number of real chars in read packet */
- Xunsigned char *nameptr; /* ptr in filename for MODEM7 protocol */
- Xtime_t start; /* starting time of transfer */
- Xint openflag = FALSE; /* is file open for writing? */
- X
- Xlogit("----\nXMODEM File Receive Function\n");
- Xtlogit("----\nXMODEM File Receive Function\n");
- Xif (CRCMODE)
- X {
- X logit("CRC mode requested on command line\n");
- X tlogit("CRC mode requested on command line\n");
- X }
- X
- Xif (YMODEMG)
- X {
- X logit("YMODEM-G mode requested on command line\n");
- X tlogit("YMODEM-G mode requested on command line\n");
- X }
- X
- XBATCH = FALSE; /* don't know if really are in batch mode ! */
- Xfatalerror = FALSE;
- Xfirstwait = WAITFIRST; /* For first packet, wait short time */
- Xsectnum = errors = recvsectcnt = 0;
- Xbufsize = 128;
- Xmodtime = 0l; filemode = 0;
- Xserial = 0; filesleft = 0; totalleft = 0l; yfiletype = 0;
- Xfilelength = 0l; fileread =0l; CHECKLENGTH = FALSE;
- Xnocancanabort = FALSE;
- X
- Xtmode = (XMITTYPE == 't') ? TRUE : FALSE;
- Xamode = (XMITTYPE == 'a') ? TRUE : FALSE;
- X
- X/* start up transfer */
- X
- Xsterrors = 0;
- Xflushin(); /* flush input queue */
- X
- Xif (YMODEMG)
- X sendbyte(GCHR);
- Xelse if (CRCMODE && !MDM7BAT)
- X{
- X sendbyte(CRCCHR);
- X if (LONGPACK && !MDM7BAT)
- X sendbyte(KCHR);
- X}
- Xelse
- X sendbyte(NAK);
- X
- X
- Xdo /* start of MAIN Do-While loop to read packets */
- X{
- X errorflag = FALSE;
- X do /* start by reading first byte in packet */
- X {
- X firstchar = readbyte(firstwait);
- X }
- X while ((firstchar != SOH)
- X && (firstchar != STX)
- X && (firstchar != EOT)
- X && (firstchar != ACK || recvsectcnt > 0)
- X && (firstchar != TIMEOUT)
- X && (firstchar != CAN || nocancanabort));
- X
- X if (firstchar == EOT && !NOEOT) /* check for REAL EOT */
- X {
- X flushin();
- X sendbyte(NAK); /* NAK the EOT */
- X if ((firstchar = readbyte(5)) != EOT) /* check next character */
- X {
- X logit("Spurious EOT detected; ignored\n");
- X tlogit("Spurious EOT detected; ignored\n");
- X if ((firstchar == SOH) || (firstchar == STX) ||
- X (firstchar == ACK && recvsectcnt == 0) ||
- X (firstchar == CAN && !nocancanabort) ||
- X (firstchar == TIMEOUT))
- X ;
- X else
- X {
- X firstchar = 0;
- X errorflag = TRUE;
- X }
- X }
- X }
- X
- X if (firstchar == TIMEOUT) /* timeout? */
- X {
- X if (recvsectcnt > 0)
- X {
- X logitarg("Timeout on Sector %s\n", sectdisp(recvsectcnt,bufsize,1));
- X tlogitarg("Timeout on Sector %s\n", sectdisp(recvsectcnt,bufsize,1));
- X }
- X errorflag = TRUE;
- X }
- X
- X if (firstchar == CAN) /* bailing out? (only at beginning or if CANCAN flag set) */
- X {
- X if ((readbyte(3) & 0x7f) == CAN)
- X {
- X if (openflag)
- X {
- X close(fd);
- X unlink(name);
- X error("Reception Canceled by CAN-CAN; partial file deleted",TRUE);
- X }
- X else
- X error("Reception Canceled by CAN-CAN",TRUE);
- X }
- X else
- X {
- X errorflag = TRUE;
- X logit("Received single CAN character\n");
- X tlogit("Received single CAN character\n");
- X }
- X }
- X
- X if (firstchar == ACK) /* MODEM7 batch? (only at beginning) */
- X {
- X int i,c;
- X
- X logit("MODEM7 Batch Protocol\n");
- X tlogit("MODEM7 Batch Protocol\n");
- X nameptr = buff;
- X checksum = 0;
- X
- X for (i=0; i<NAMSIZ; i++)
- X {
- X c = readbyte(3);
- X
- X if (c == CAN)
- X {
- X if (readbyte(3) == CAN)
- X error("Program Canceled by CAN-CAN", TRUE);
- X else
- X {
- X logit("Received single CAN character in MODEM7 filename\n");
- X tlogit("Received single CAN character in MODEM7 filename\n");
- X errorflag = TRUE;
- X break;
- X }
- X }
- X
- X if (c == EOT && i == 0)
- X {
- X sendbyte(ACK); /* acknowledge EOT */
- X logit("MODEM7 Batch Receive Complete\n");
- X tlogit("MODEM7 Batch Receive Complete\n");
- X return (FALSE);
- X }
- X
- X if (c == TIMEOUT)
- X {
- X logit("Timeout waiting for MODEM7 filename character\n");
- X tlogit("Timeout waiting for MODEM7 filename character\n");
- X errorflag = TRUE;
- X break;
- X }
- X
- X if (c == BAD_NAME)
- X {
- X logit("Error during MODEM7 filename transfer\n");
- X tlogit("Error during MODEM7 filename transfer\n");
- X errorflag = TRUE;
- X break;
- X }
- X
- X *nameptr++ = c;
- X checksum += c;
- X sendbyte(ACK);
- X }
- X
- X if (!errorflag)
- X {
- X c = readbyte(3);
- X if (c == CTRLZ) /* OK; end of string found */
- X {
- X sendbyte(checksum + CTRLZ);
- X if (readbyte(15) == ACK) /* file name found! */
- X {
- X xmdebug("MODEM7 file name OK");
- X *nameptr = '\000'; /* unixify the file name */
- X name = cpm_unix(buff);
- X BATCH = TRUE;
- X logitarg("MODEM7 file name: %s\n", name);
- X tlogitarg("MODEM7 file name: %s\n", name);
- X errors = 0; /* restart crc handshake */
- X sleep(2); /* give other side a chance */
- X }
- X else
- X {
- X logit("Checksum error in MODEM7 filename\n");
- X tlogit("Checksum error in MODEM7 filename\n");
- X errorflag = TRUE;
- X }
- X }
- X else
- X {
- X logit("Length error in MODEM7 filename\n");
- X tlogit("Length error in MODEM7 filename\n");
- X errorflag = TRUE;
- X }
- X }
- X }
- X
- X
- X if (firstchar == SOH || firstchar == STX) /* start reading packet */
- X {
- X bufsize = (firstchar == SOH) ? 128 : 1024;
- X
- X if (recvsectcnt == 0) /* 1st data packet, initialize */
- X {
- X if (bufsize == 1024)
- X {
- X logit("1K packet mode chosen\n");
- X tlogit("1K packet mode chosen\n");
- X }
- X start = time((time_t *) 0);
- X errors = 0;
- X firstwait = 5;
- X }
- X
- X sectcurr = readbyte(3);
- X sectcomp = readbyte(3);
- X if ((sectcurr + sectcomp) == 0xff) /* is packet number checksum correct? */
- X {
- X if (sectcurr == ((sectnum+1) & 0xff)) /* is packet number correct? */
- X {
- X if (DEBUG)
- X fprintf(LOGFP,"DEBUG: packet with sector number %d started\n", sectnum);
- X
- X /* Read, process and calculate checksum for a buffer of data */
- X
- X readbackup = fileread;
- X if (readbuf(bufsize, 1, tmode, amode, recvsectcnt, &checksum, &bufctr) != TIMEOUT)
- X {
- X
- X /* verify checksum or CRC */
- X
- X if (CRCMODE)
- X {
- X checksum &= 0xffff;
- X inchecksum = readbyte(3); /* get 16-bit CRC */
- X inchecksum = (inchecksum<<8) | readbyte(3);
- X }
- X
- X else
- X inchecksum = readbyte(3); /* get simple 8-bit checksum */
- X
- X if (inchecksum == checksum) /* good checksum, hence good packet */
- X {
- X xmdebug("checksum ok");
- X errors = 0;
- X recvsectcnt += (bufsize == 128) ? 1 : 8;
- X nocancanabort = CANCAN ? FALSE : TRUE;
- X sectnum = sectcurr;
- X
- X if (!openflag) /* open output file if necessary */
- X {
- X openflag = TRUE;
- X if ((fd = creat(name, CREATMODE)) < 0)
- X {
- X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
- X error("Can't create file for receive", TRUE);
- X }
- X if (!BATCH)
- X {
- X logitarg("File Name: %s\n", name);
- X tlogitarg("File Name: %s\n", name);
- X }
- X }
- X
- X if (write(fd, (char *) buff, bufctr) != bufctr)
- X {
- X close(fd);
- X unlink(name);
- X error("File Write Error", TRUE);
- X }
- X else
- X {
- X if (TIPFLAG && recvsectcnt % 32 == 0)
- X tlogitarg("Sector %s received\n", sectdisp(recvsectcnt,bufsize,0));
- X if (!YMODEMG)
- X {
- X flushin(); /* flush input */
- X sendbyte(ACK); /* ACK the received packet */
- X }
- X }
- X }
- X
- X /* Start handling various errors and special conditions */
- X
- X else /* bad checksum */
- X {
- X logitarg("Checksum Error on Sector %s: ", sectdisp(recvsectcnt,bufsize,1));
- X logitarg("sent=%x ", inchecksum);
- X logitarg("recvd=%x\n", checksum);
- X tlogitarg("Checksum Error on Sector %s: ", sectdisp(recvsectcnt,bufsize,1));
- X tlogitarg("sent=%x ", inchecksum);
- X tlogitarg("recvd=%x\n", checksum);
- X fileread = readbackup;
- X errorflag = TRUE;
- X if (YMODEMG)
- X fatalerror = TRUE;
- X }
- X }
- X
- X else /* read timeout */
- X {
- X logitarg("Timeout while reading sector %s\n",sectdisp(recvsectcnt,bufsize,1));
- X tlogitarg("Timeout while reading sector %s\n",sectdisp(recvsectcnt,bufsize,1));
- X fileread = readbackup;
- X errorflag = TRUE;
- X if (YMODEMG)
- X fatalerror = TRUE;
- X }
- X }
- X
- X else /* sector number is wrong OR Ymodem filename */
- X {
- X if (sectcurr == 0 && recvsectcnt == 0) /* Ymodem file-name packet */
- X {
- X logit("YMODEM Batch Protocol\n");
- X tlogit("YMODEM Batch Protocol\n");
- X
- X /* Read and process a file-name packet */
- X
- X if (readbuf(bufsize, 1, FALSE, FALSE, recvsectcnt, &checksum, &bufctr) != TIMEOUT)
- X {
- X
- X /* verify checksum or CRC */
- X
- X if (CRCMODE)
- X {
- X checksum &= 0xffff;
- X inchecksum = readbyte(3); /* get 16-bit CRC */
- X inchecksum = (inchecksum<<8) | readbyte(3);
- X }
- X
- X else
- X inchecksum = readbyte(3); /* get simple 8-bit checksum */
- X
- X if (inchecksum == checksum) /* good checksum, hence good filename */
- X {
- X xmdebug("checksum ok");
- X strcpy(name, (char *)buff);
- X expsect = ((buff[bufsize-1]<<8) | buff[bufsize-2]);
- X BATCH = TRUE;
- X YMDMBAT = TRUE;
- X if (strlen(name) == 0) /* check for no more files */
- X {
- X flushin(); /* flush input */
- X sendbyte(ACK); /* ACK the packet */
- X logit("YMODEM Batch Receive Complete\n");
- X tlogit("YMODEM Batch Receive Complete\n");
- X return (FALSE);
- X }
- X unixify(name); /* make filename canonical */
- X
- X /* read rest of YMODEM header */
- X p = (char *)buff + strlen((char *)buff) + 1;
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG: header info: %s\n", p);
- X sscanf(p, "%ld%lo%o%o%d%ld%d",
- X &filelength, &modtime, &filemode,
- X &serial, &filesleft, &totalleft,
- X &yfiletype);
- X logitarg("YMODEM file name: %s\n", name);
- X tlogitarg("YMODEM file name: %s\n", name);
- X fileread = 0l;
- X if (filelength)
- X {
- X CHECKLENGTH = TRUE;
- X logitarg("YMODEM file size: %ld\n", filelength);
- X tlogitarg("YMODEM file size: %ld\n", filelength);
- X }
- X else if (expsect)
- X logitarg("YMODEM estimated file length %d sectors\n", expsect);
- X if (modtime)
- X {
- X logitarg("YMODEM file date: %s", ctime((time_t *)&modtime));
- X }
- X if (filemode)
- X logitarg("YMODEM file mode: %o\n", filemode);
- X
- X if (filesleft)
- X {
- X logitarg("YMODEM %d file(s) left to receive ", filesleft);
- X logitarg("containing %ld bytes\n", totalleft);
- X tlogitarg("YMODEM %d file(s) left to receive ", filesleft);
- X tlogitarg("containing %ld bytes\n", totalleft);
- X }
- X if (serial)
- X logitarg("YMODEM sender's serial number: %d\n", serial);
- X if (yfiletype)
- X logitarg("YMODEM file type %d\n", yfiletype);
- X
- X openflag = TRUE; /* open the file for writing */
- X if ((fd = creat(name, CREATMODE)) < 0)
- X {
- X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
- X error("Can't create file for receive", TRUE);
- X }
- X if (!YMODEMG)
- X {
- X flushin(); /* flush the input stream */
- X sendbyte(ACK); /* ACK the filename packet */
- X }
- X /* do initial handshake to start file transfer */
- X if (YMODEMG)
- X sendbyte(GCHR);
- X else if (CRCMODE)
- X {
- X sendbyte(CRCCHR);
- X if (LONGPACK)
- X sendbyte(KCHR);
- X }
- X else
- X sendbyte(NAK);
- X firstwait = WAITFIRST; /* reset waiting time */
- X }
- X
- X else /* bad filename checksum */
- X {
- X logit("checksum error on filename sector\n");
- X tlogit("checksum error on filename sector\n");
- X errorflag = TRUE;
- X if (YMODEMG)
- X fatalerror = TRUE;
- X }
- X }
- X else
- X {
- X logit("Timeout while reading filename packet\n");
- X tlogit("Timeout while reading filename packet\n");
- X errorflag = TRUE;
- X if (YMODEMG)
- X fatalerror = TRUE;
- X }
- X }
- X
- X else if (sectcurr == sectnum) /* duplicate sector? */
- X {
- X logitarg("Duplicate sector %s flushed\n", sectdisp(recvsectcnt,bufsize,0));
- X tlogitarg("Duplicate sector %s flushed\n", sectdisp(recvsectcnt,bufsize,0));
- X if (YMODEMG)
- X {
- X errorflag = TRUE;
- X fatalerror = TRUE;
- X }
- X else
- X {
- X flushin(); /* REALLY flush input */
- X while(readbyte(1) != TIMEOUT)
- X ;
- X sendbyte(ACK);
- X }
- X }
- X else /* no, real phase error */
- X {
- X logitarg("Phase Error - Expected packet is %s\n", sectdisp(recvsectcnt,bufsize,1));
- X tlogitarg("Phase Error - Expected packet is %s\n", sectdisp(recvsectcnt,bufsize,1));
- X errorflag = TRUE;
- X fatalerror = TRUE;
- X }
- X }
- X }
- X
- X else /* bad packet number checksum */
- X {
- X logitarg("Header Sector Number Error on Sector %s\n", sectdisp(recvsectcnt, bufsize,1));
- X tlogitarg("Header Sector Number Error on Sector %s\n", sectdisp(recvsectcnt, bufsize,1));
- X errorflag = TRUE;
- X if (YMODEMG)
- X fatalerror = TRUE;
- X }
- X
- X } /* END reading packet loop */
- X
- X if (errorflag && !fatalerror && recvsectcnt != 0) /* Handle errors */
- X {
- X errors++;
- X
- X if (errors >= ERRORMAX) /* over error limit? */
- X fatalerror = TRUE;
- X else /* flush input and NAK the packet */
- X {
- X flushin();
- X while (readbyte(2) != TIMEOUT) /* wait for line to settle */
- X ;
- X sendbyte(NAK);
- X }
- X }
- X
- X if (recvsectcnt == 0 && errorflag && !fatalerror && firstchar != EOT) /* handle startup handshake */
- X {
- X sterrors++;
- X
- X if (sterrors >= STERRORMAX)
- X fatalerror = TRUE;
- X
- X else if (CRCMODE && MDM7BAT && !BATCH)
- X sendbyte(NAK);
- X
- X else if (CRCMODE && sterrors == CRCSWMAX && !YMDMBAT)
- X {
- X CRCMODE = FALSE;
- X logit("Sender not accepting CRC request, changing to checksum\n");
- X tlogit("Sender not accepting CRC request, changing to checksum\n");
- X sendbyte(NAK);
- X }
- X
- X else if (!CRCMODE && sterrors == CRCSWMAX && !YMDMBAT)
- X {
- X CRCMODE = TRUE;
- X logit("Sender not accepting checksum request, changing to CRC\n");
- X tlogit("Sender not accepting checksum request, changing to CRC\n");
- X sendbyte(CRCCHR);
- X if (LONGPACK && !MDM7BAT)
- X sendbyte(KCHR);
- X }
- X
- X else if (YMODEMG)
- X sendbyte(GCHR);
- X
- X else if (CRCMODE)
- X {
- X sendbyte(CRCCHR);
- X if (LONGPACK && !MDM7BAT)
- X sendbyte(KCHR);
- X }
- X
- X else
- X sendbyte(NAK);
- X }
- X}
- Xwhile ((firstchar != EOT) && !fatalerror); /* end of MAIN Do-While */
- X
- Xif ((firstchar == EOT) && !fatalerror) /* normal exit? */
- X{
- X if (openflag) /* close the file */
- X close(fd);
- X sendbyte(ACK); /* ACK the EOT */
- X logit("Receive Complete\n");
- X tlogit("Receive Complete\n");
- X if (LOGFLAG)
- X prtime (recvsectcnt, time((time_t *) 0) - start, LOGFP);
- X if (TIPFLAG)
- X prtime (recvsectcnt, time((time_t *) 0) - start, stderr);
- X
- X if (openflag && modtime) /* set file modification time */
- X {
- X timep[0] = time((time_t *) 0);
- X timep[1] = modtime;
- X utime(name, timep);
- X }
- X
- X if (BATCH) /* send appropriate return code */
- X return(TRUE);
- X else
- X return(FALSE);
- X}
- Xelse /* no, error exit */
- X{
- X if (openflag)
- X {
- X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
- X close(fd);
- X unlink(name);
- X flushin();
- X while (readbyte(2) != TIMEOUT) /* wait for line to settle */
- X ;
- X error("ABORTED -- Too Many Errors -- Deleting File", TRUE);
- X }
- X else if (recvsectcnt != 0)
- X {
- X sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN); sendbyte(CAN);
- X flushin();
- X while (readbyte(2) != TIMEOUT) /* wait for line to settle */
- X ;
- X error("ABORTED -- Too Many Errors", TRUE);
- X }
- X else
- X {
- X flushin();
- X while (readbyte(2) != TIMEOUT) /* wait for line to settle */
- X ;
- X error("ABORTED -- Remote system is not responding", TRUE);
- X }
- X
- X}
- X
- Xreturn(FALSE);
- X}
- END_OF_FILE
- if test 17709 -ne `wc -c <'receive.c'`; then
- echo shar: \"'receive.c'\" unpacked with wrong size!
- fi
- # end of 'receive.c'
- fi
- if test -f 'xmodem.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xmodem.c'\"
- else
- echo shar: Extracting \"'xmodem.c'\" \(8438 characters\)
- sed "s/^X//" >'xmodem.c' <<'END_OF_FILE'
- X/*
- X * XMODEM -- Implements the Christensen XMODEM protocol,
- X * for packetized file up/downloading.
- X *
- X * See the README file for some notes on SYS V adaptations.
- X * The program has been successfully run on VAXes (4.3BSD) and SUN-3/4s
- X * (SunOS 3.x) against MEX-PC and ZCOMM/DSZ.
- X *
- X * See the README and update.doc files for history and change notes.
- X *
- X * Please send bug fixes, additions and comments to:
- X * grandi@noao.edu
- X */
- X
- X#include "xmodem.h"
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X char *getenv();
- X FILE *fopen();
- X char *unix_cpm();
- X char *strcpy();
- X char *strcat();
- X char *prtype();
- X
- X char *fname = filename; /* convenient place to stash file names */
- X char *logfile = "xmodem.log"; /* Name of LOG File */
- X
- X char *stamptime(); /* for timestamp */
- X
- X char *defname = "xmodem.in"; /* default file name if none given */
- X
- X struct stat filestatbuf; /* file status info */
- X
- X int index;
- X char flag;
- X long expsect;
- X int fd;
- X
- X /* initialize option flags */
- X
- X XMITTYPE = 't'; /* assume text transfer */
- X DEBUG = FALSE; /* keep debugging info in log */
- X RECVFLAG = FALSE; /* not receive */
- X SENDFLAG = FALSE; /* not send either */
- X BATCH = FALSE; /* nor batch */
- X CRCMODE = FALSE; /* use checksums for now */
- X DELFLAG = FALSE; /* don't delete old log file */
- X LOGFLAG = TRUE; /* keep log */
- X LONGPACK = FALSE; /* do not use long packets on transmit */
- X MDM7BAT = FALSE; /* no MODEM7 batch mode */
- X YMDMBAT = FALSE; /* no YMODEM batch mode */
- X TOOBUSY = FALSE; /* not too busy for sleeping in packet read */
- X TIPFLAG = FALSE; /* no special logging on stderr */
- X DELAYFLAG = FALSE; /* don't delay startup for a while */
- X NOEOT = FALSE; /* don't suppress EOT verification */
- X CANCAN = FALSE; /* don't allow CAN-CAN aborts in mid-transfer */
- X YMODEMG = FALSE; /* no YMODEM-G */
- X
- X fprintf(stderr, "XMODEM Version %s", VERSION);
- X fprintf(stderr, " -- UNIX-Microcomputer File Transfer Facility\n");
- X
- X if (argc == 1)
- X {
- X help();
- X exit(-1);
- X }
- X
- X index = 0; /* set index for flag loop */
- X
- X stopsig(); /* suppress keyboard stop signal */
- X
- X while ((flag = argv[1][index++]) != '\0')
- X switch (flag) {
- X case '-' : break;
- X case 'X' :
- X case 'x' : DEBUG = TRUE; /* turn on debugging log */
- X break;
- X case 'C' :
- X case 'c' : CRCMODE = TRUE; /* enable CRC on receive */
- X break;
- X case 'D' :
- X case 'd' : DELFLAG = TRUE; /* delete log file */
- X break;
- X case 'L' :
- X case 'l' : LOGFLAG = FALSE; /* turn off log */
- X break;
- X case 'm' :
- X case 'M' : MDM7BAT = TRUE; /* turn on MODEM7 batch protocol */
- X BATCH = TRUE;
- X break;
- X case 'y' :
- X case 'Y' : YMDMBAT = TRUE; /* turn on YMODEM batch protocol */
- X BATCH = TRUE;
- X break;
- X case 'k' :
- X case 'K' : LONGPACK = TRUE; /* use 1K packets on transmit */
- X break;
- X case 't' :
- X case 'T' : TOOBUSY = TRUE; /* turn off sleeping */
- X break;
- X case 'p' :
- X case 'P' : TIPFLAG = TRUE; /* turn on special handling for SunOS tip */
- X break;
- X case 'w' :
- X case 'W' : DELAYFLAG = TRUE; /* delay startup */
- X break;
- X case 'e' :
- X case 'E' : NOEOT = TRUE; /* turn off EOT verification */
- X break;
- X case 'n' :
- X case 'N' : CANCAN = TRUE; /* allow mid-transfer CAN-CAN */
- X break;
- X case 'g' :
- X case 'G' : YMODEMG = TRUE; /* YMODEM-G mode */
- X CANCAN = TRUE;
- X CRCMODE = TRUE;
- X YMDMBAT = TRUE;
- X break;
- X case 'R' :
- X case 'r' : RECVFLAG = TRUE; /* receive file */
- X XMITTYPE = gettype(argv[1][index++]); /* get t/b */
- X break;
- X case 'S' :
- X case 's' : SENDFLAG = TRUE; /* send file */
- X XMITTYPE = gettype(argv[1][index++]);
- X break;
- X default : fprintf(stderr, "Invalid Flag %c ignored\n", flag);
- X break;
- X }
- X
- X if (DEBUG)
- X LOGFLAG = TRUE;
- X
- X if (LOGFLAG)
- X {
- X if ((fname = getenv("HOME")) == 0) /* Get HOME variable */
- X error("XMODEM Fatal Error- Can't get Environment!", FALSE);
- X fname = strcat(fname, "/");
- X fname = strcat(fname, logfile);
- X if (!DELFLAG)
- X LOGFP = fopen(fname, "a"); /* append to LOG file */
- X else
- X LOGFP = fopen(fname, "w"); /* new LOG file */
- X if (!LOGFP)
- X error("XMODEM Fatal Error- Can't Open Log File", FALSE);
- X
- X fprintf(LOGFP,"\n++++++++ %s", stamptime());
- X fprintf(LOGFP,"XMODEM Version %s\n", VERSION);
- X fprintf(LOGFP,"Command line: %s %s", argv[0], argv[1]);
- X for (index=2; index<argc; ++index)
- X fprintf(LOGFP, " %s", argv[index]);
- X fprintf(LOGFP, "\n");
- X }
- X
- X getspeed(); /* get tty-speed for time estimates */
- X
- X if (RECVFLAG && SENDFLAG)
- X error("XMODEM Fatal Error- Both Send and Receive Functions Specified", FALSE);
- X
- X if (MDM7BAT && (YMDMBAT || YMODEMG))
- X error("XMODEM Fatal Error - Both YMODEM and MODEM7 Batch Protocols Specified", FALSE);
- X
- X if (!RECVFLAG && !SENDFLAG)
- X error("XMODEM Fatal Error - Either Send or Receive Function must be chosen!",FALSE);
- X
- X if (SENDFLAG && argc==2)
- X error("XMODEM Fatal Error - No file specified to send",FALSE);
- X
- X if (RECVFLAG && argc==2)
- X {
- X /* assume we really want CRC-16 in batch, unless we specify MODEM7 mode, unless we explicitly set CRCMODE */
- X if (!CRCMODE)
- X CRCMODE = MDM7BAT ? FALSE : TRUE;
- X fprintf(stderr, "Ready for BATCH RECEIVE");
- X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
- X if (!TIPFLAG)
- X fprintf(stderr, "Send several Control-X characters to cancel\n");
- X logit("Batch Receive Started");
- X logitarg(" in %s mode\n", prtype(XMITTYPE));
- X strcpy(fname, defname);
- X }
- X
- X if (RECVFLAG && argc>2)
- X {
- X if(open(argv[2], 0) != -1) /* check for overwriting */
- X {
- X logit("Warning -- Target File Exists and is Being Overwritten\n");
- X fprintf(stderr, "Warning -- Target File Exists and is Being Overwritten\n");
- X }
- X fprintf(stderr, "Ready to RECEIVE File %s", argv[2]);
- X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
- X if (!TIPFLAG)
- X fprintf(stderr, "Send several Control-X characters to cancel\n");
- X logitarg("Receiving in %s mode\n", prtype(XMITTYPE));
- X strcpy(fname,argv[2]);
- X }
- X
- X if (RECVFLAG)
- X {
- X if (DELAYFLAG) /* delay if -w requested */
- X sleep(TIPDELAY);
- X setmodes(); /* set tty modes for transfer */
- X
- X while(rfile(fname) != FALSE); /* receive files */
- X
- X flushin();
- X restoremodes(FALSE); /* restore normal tty modes */
- X
- X sleep(2); /* give other side time to return to terminal mode */
- X exit(0);
- X }
- X
- X if (SENDFLAG && BATCH)
- X {
- X if (YMDMBAT)
- X {
- X ytotleft = 0l;
- X yfilesleft = 0;
- X for (index=2; index<argc; index++) {
- X if (stat(argv[index], &filestatbuf) == 0) {
- X yfilesleft++;
- X ytotleft += filestatbuf.st_size;
- X if (XMITTYPE == 't') {
- X if((fd=open(argv[index],0)) >= 0) {
- X ytotleft += countnl(fd);
- X close(fd);
- X }
- X }
- X }
- X }
- X if (DEBUG)
- X fprintf(LOGFP, "DEBUG YMODEM file count: %d, %ld bytes\n", yfilesleft, ytotleft);
- X
- X fprintf(stderr, "Ready to YMODEM BATCH SEND");
- X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
- X logit("YMODEM Batch Send Started");
- X logitarg(" in %s mode\n", prtype(XMITTYPE));
- X }
- X else if (MDM7BAT)
- X {
- X fprintf(stderr, "Ready to MODEM7 BATCH SEND");
- X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
- X logit("MODEM7 Batch Send Started");
- X logitarg(" in %s mode\n", prtype(XMITTYPE));
- X }
- X if (!TIPFLAG)
- X fprintf(stderr, "Send several Control-X characters to cancel\n");
- X
- X if (DELAYFLAG) /* delay if -w requested */
- X sleep(TIPDELAY);
- X setmodes();
- X for (index=2; index<argc; index++) {
- X if (stat(argv[index], &filestatbuf) < 0) {
- X logitarg("\nFile %s not found\n", argv[index]);
- X tlogitarg("\nFile %s not found\n", argv[index]);
- X continue;
- X }
- X sfile(argv[index]);
- X }
- X sfile("");
- X flushin();
- X restoremodes(FALSE);
- X
- X logit("Batch Send Complete\n");
- X tlogit("Batch Send Complete\n");
- X sleep(2);
- X exit (0);
- X }
- X
- X if (SENDFLAG && !BATCH)
- X {
- X if (stat(argv[2], &filestatbuf) < 0)
- X error("Can't find requested file", FALSE);
- X expsect = (filestatbuf.st_size/128)+1;
- X
- X fprintf(stderr, "File %s Ready to SEND", argv[2]);
- X fprintf(stderr, " in %s mode\n", prtype(XMITTYPE));
- X fprintf(stderr, "Estimated File Size %ldK, %ld Sectors, %ld Bytes\n",
- X (filestatbuf.st_size/1024)+1, expsect,
- X filestatbuf.st_size);
- X projtime(expsect, stdout);
- X if (!TIPFLAG)
- X fprintf(stderr, "Send several Control-X characters to cancel\n");
- X logitarg("Sending in %s mode\n", prtype(XMITTYPE));
- X
- X setmodes();
- X sfile(argv[2]);
- X flushin();
- X restoremodes(FALSE);
- X
- X sleep(2);
- X exit(0);
- X }
- X}
- END_OF_FILE
- if test 8438 -ne `wc -c <'xmodem.c'`; then
- echo shar: \"'xmodem.c'\" unpacked with wrong size!
- fi
- # end of 'xmodem.c'
- fi
- echo shar: End of archive 1 \(of 3\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-